﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ExpressionUtil.UnitTest
{
    /// <summary>
    /// NodeUnitTest 的摘要说明
    /// </summary>
    [TestClass]
    public class NodeUnitTest
    {
        public NodeUnitTest()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///获取或设置测试上下文，该上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region 附加测试特性
        //
        // 编写测试时，可以使用以下附加特性:
        //
        // 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // 在运行每个测试之前，使用 TestInitialize 来运行代码
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // 在每个测试运行完之后，使用 TestCleanup 来运行代码
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void AbsFunctionNodeTest()
        {
            Expression exp = new Expression("abs(-1)");
            Assert.AreEqual(exp.DecimalResult, 1);
        }

        [TestMethod]
        public void AddNodeTest()
        {
            Expression exp = new Expression("1+1+1+1+2+1");
            Assert.AreEqual(exp.DecimalResult, 7);
        }

        [TestMethod]
        public void AndNodeTest()
        {
            Expression exp = new Expression("true&&false");
            Assert.AreEqual(exp.BoolResult, false);
        }

        [TestMethod]
        public void AvgFunctionNodeTest()
        {
            Expression exp = new Expression("avg(2,12)");
            Assert.AreEqual(exp.DecimalResult, 7);
        }

        [TestMethod]
        public void ConstBoolNodeTest()
        {
            Expression exp = new Expression("true");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void ConstNumberNodeTest()
        {
            Expression exp = new Expression("2");
            Assert.AreEqual(exp.DecimalResult, 2);
        }

        [TestMethod]
        public void DivisionNodeTest()
        {
            Expression exp = new Expression("4/2");
            Assert.AreEqual(exp.DecimalResult, 2);
        }

        [TestMethod]
        public void EqualNodeTest()
        {
            Expression exp = new Expression("2==2");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void ExpFunctionNodeTest()
        {
            Expression exp = new Expression("exp(2)");
            Assert.AreEqual(exp.DecimalResult, (decimal)(Math.Exp(2)));
        }

        [TestMethod]
        public void GreaterOrEqualNodeTest()
        {
            Expression exp = new Expression("2>=1");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void GreaterThanNodeTest()
        {
            Expression exp = new Expression("2>1");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void IfElseIfFunctionNodeTest()
        {
            Expression exp = new Expression("IfElseIf(2>1,0,1)");
            Assert.AreEqual(exp.DecimalResult, 0);
        }

        [TestMethod]
        public void LeftShiftNodeTest()
        {
            Expression exp = new Expression("1<<1");
            Assert.AreEqual(exp.DecimalResult, 2);
        }

        [TestMethod]
        public void LessOrEqualNodeTest()
        {
            Expression exp = new Expression("1<=1");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void LessThanNodeTest()
        {
            Expression exp = new Expression("1<1");
            Assert.AreEqual(exp.BoolResult, false);
        }

        [TestMethod]
        public void LogicAndNodeTest()
        {
            Expression exp = new Expression("0&1");
            Assert.AreEqual(exp.DecimalResult, 0);
        }

        [TestMethod]
        public void LogicNotNodeTest()
        {
            Expression exp = new Expression("~0");
            Assert.AreEqual(exp.DecimalResult, -1);
        }

        [TestMethod]
        public void LogicOrNodeTest()
        {
            Expression exp = new Expression("0|1");
            Assert.AreEqual(exp.DecimalResult, 1);
        }

        [TestMethod]
        public void MultiplicationNodeTest()
        {
            Expression exp = new Expression("2*10");
            Assert.AreEqual(exp.DecimalResult, 20);
        }

        [TestMethod]
        public void NegativeNodeTest()
        {
            Expression exp = new Expression("-1");
            Assert.AreEqual(exp.DecimalResult, -1);
        }

        [TestMethod]
        public void NotNodeTest()
        {
            Expression exp = new Expression("!true");
            Assert.AreEqual(exp.BoolResult, false);
        }

        [TestMethod]
        public void OrNodeTest()
        {
            Expression exp = new Expression("true||false");
            Assert.AreEqual(exp.BoolResult, true);
        }

        [TestMethod]
        public void PositiveNodeTest()
        {
            Expression exp = new Expression("+2");
            Assert.AreEqual(exp.DecimalResult, 2);
        }

        [TestMethod]
        public void RightShiftNodeTest()
        {
            Expression exp = new Expression("2>>1");
            Assert.AreEqual(exp.DecimalResult, 1);
        }

        [TestMethod]
        public void RoundFunctionNodeTest()
        {
            Expression exp = new Expression("round(1.12,1)");
            Assert.AreEqual(exp.DecimalResult, 1.1m);
        }

        [TestMethod]
        public void SubtractNodeTest()
        {
            Expression exp = new Expression("10-1");
            Assert.AreEqual(exp.DecimalResult, 9);
        }

        [TestMethod]
        public void SumFunctionNodeTest()
        {
            Expression exp = new Expression("sum(1,1,1,1,1)");
            Assert.AreEqual(exp.DecimalResult, 5);
        }

        [TestMethod]
        public void TruncFunctionNodeTest()
        {
            Expression exp = new Expression("trunc(1.1)");
            Assert.AreEqual(exp.DecimalResult, 1);
        }

        [TestMethod]
        public void VariableNodeTest()
        {
            Expression exp = new Expression("a+b");
            exp.SetVariableValue("a", 1);
            exp.SetVariableValue("b", 1);
            Assert.AreEqual(exp.DecimalResult, 2);
            exp.Expr = "a";
            exp.SetVariableValue("a", true);
            Assert.AreEqual(exp.BoolResult, true);
        }
    }
}
